package de.fhffm.gaertnerei.gui;
/**
 * @author Michael Wyrzykowski & Julian Schmücker
 */

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.gaertnerei.exceptions.EingabeException;
import de.fhffm.gaertnerei.tabellen.Aussaat;
import de.fhffm.gaertnerei.tabellen.Wachstum;

public class WachstumFenster implements ActionListener {
	
	private String keimungString = null;
	private String datumString = null;
	private String groesseString = null;
	private String aussaatDatumString = null;
	
	private Double groesseDouble = 0.0;
	
	private JTextField textfeldKeimung = new JTextField(8);
	private JTextField textfeldGroesse = new JTextField(8);
	
	private JFormattedTextField textfeldDatum ;
	
	private JLabel labelKeimung = new JLabel(" Keimung :");
	private JLabel labelGroesse = new JLabel(" Größe (cm) :");
	private JLabel labelDatum = new JLabel(" Datum :");
	private JLabel labelInfo = new JLabel();
	

	private JButton buttonSpeichern = new JButton("Speichern");
	private JButton buttonAbbrechen = new JButton("Abbrechen");
	
	private JPanel panelEingabe = new JPanel(new GridLayout(4,2));
	private JPanel panelButton = new JPanel();
	private JPanel panelInfo = new JPanel();
	
	private JFrame wachstumFrame = new JFrame();
	
	private List<String> ausgewaehlteZeile;
	
	private StringBuilder stringBuilder = new StringBuilder();
	
	private MaskFormatter datumFormat= null;
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private Date aktuellesDatum = new Date();
	private Date eingegebenesDatum;
	private Date aussaatDatum;
	
	private Wachstum wachstum;
	
	private boolean wachstumVorhanden = false;
	
	private int wachstumID; 	

	public WachstumFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		
		erstelleFenster();
		setzeInfo();
		setzeEingaben();
		setzeButton();
		setzePanel();		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource();

		if (obj == buttonAbbrechen) {	
			wachstumFrame.dispose();
		}
		
		if(obj == buttonSpeichern){
	
			/*
			 * Eingabe wird überprüft wenn alles OK ist
			 * dan wird überprüft ob das Wachstum neu hinzugefügt oder 
			 * geupdatet werden muss.
			 * Falls es geupdatet wird, wird nochmal überprüft ob das Update
			 * nicht evtl abgebrochen wurde, weil der nutzer darauf hingewiesen
			 * wurde das der vorherige Wachstum gelöscht wird und er das nicht möchte
			 */
			
			if(ueberpruefeEingabe()){
				
				if(wachstumVorhanden){
					
					if(doUpdateWachstum()){
						einfügenEnde();
				
					}else{
						//Update abebrochen -> nix passiert
					}
					
				}else{
					fuegeWachstumEin();
					einfügenEnde();
				}
					
			}else{
				System.out.println("Ein Fehler ist aufgetreten");
			}
		}
	}

	private void erstelleFenster() {
		
		wachstumFrame.setSize(400,500);
		wachstumFrame.setLocationRelativeTo(null);
		wachstumFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		wachstumFrame.setVisible(true);
		wachstumFrame.setResizable(false);
		wachstumFrame.setLayout(new BorderLayout());		
		wachstumFrame.setTitle("Wachstum festlegen");		
	}

	private void setzeInfo() {
		
		stringBuilder.append("<html>Wachstum für die Aussaat mit der ID: ").append(ausgewaehlteZeile.get(0));
		stringBuilder.append("<br>").append(" vom ").append(ausgewaehlteZeile.get(1)).append(" festlegen.");
		stringBuilder.append("<br>Eingesetzte Pflanze: '").append(ausgewaehlteZeile.get(2)).append("'<br> <br>");
		
		ueberpruefeWachstum();
		stringBuilder.append("<br></html>");
		
		labelInfo.setText(stringBuilder.toString());
		panelInfo.add(labelInfo);
		stringBuilder.setLength(0);		
	}

	private void setzeEingaben() {

		panelEingabe.add(labelKeimung);
		panelEingabe.add(textfeldKeimung);
		textfeldKeimung.setToolTipText("Aktuelle Keimung der Pflanze eintragen z.B.: Sprössling");
		panelEingabe.add(labelGroesse);
		panelEingabe.add(textfeldGroesse);
		panelEingabe.add(labelDatum);
		setzeDatumAlsText();		
	}

	private void setzeButton() {

		panelButton.add(buttonSpeichern);
		panelButton.add(buttonAbbrechen);
		buttonSpeichern.addActionListener(this);
		buttonAbbrechen.addActionListener(this);
	}

	private void setzePanel() {

		wachstumFrame.getContentPane().add(panelInfo, BorderLayout.NORTH);
		wachstumFrame.getContentPane().add(panelEingabe,BorderLayout.CENTER);
		wachstumFrame.getContentPane().add(panelButton,BorderLayout.SOUTH);
		wachstumFrame.pack();		
	}

	private void ueberpruefeWachstum() {
		
		if(istWachstumVorhanden()){
			fuelleTextFelder();
		}else {
			System.out.println("Noch kein Wachstum vorhanden");
		}
	}

	private void fuelleTextFelder() {
		
		 stringBuilder.append("Für diese Aussaat gibt es ein").append("<br>vorheriges Wachstum vom ").
		 append(wachstum.getWachstumDatum()).append("<br>");
		 textfeldKeimung.setText(wachstum.getKeimung());
		 groesseString = wachstum.getGroesse();
		 String[] teilString = groesseString.split(Pattern.quote(" ")); // cm entfernen
		 textfeldGroesse.setText(teilString[0]);

	}

	private boolean istWachstumVorhanden() {

		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	

		 Wachstum wachstum = aussaat.getWachstum();
	
		em.close(); 

		try{	
		 /*Wenn es keinen vorherigen Wachstum für die Aussaat gibt wird hier eine Exception geworfen
		  * wenn dies geschieht wird die Exception gefangen und man weiß das es noch keinen Wachstum gibt
		  */
			wachstumID = wachstum.getWachstumID();
		}catch(NullPointerException e){
			wachstumVorhanden = false;
			return false;
		}
		
		this.wachstum = wachstum;
		wachstumVorhanden = true;
		return true;
	}

	private void setzeDatumAlsText() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		textfeldDatum = new JFormattedTextField(datumFormat);
		textfeldDatum.setText(simpleDateFormat.format(aktuellesDatum));
		panelEingabe.add(textfeldDatum);
	}
		
	private boolean doUpdateWachstum() {
		
		Object[] options = {"Überschreiben","Abbrechen"};
		int selected = JOptionPane.showOptionDialog(null,"Das vorherige Wachstum wird überschrieben!", "ACHTUNG!", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		switch(selected){
		case 0:
		
			System.out.println("Der aktuelle Wachstum wird überschrieben");
			EntityManagerFactory factory;
			factory = Persistence.createEntityManagerFactory("chilidatenbank");
			EntityManager em = factory.createEntityManager();
			em.getTransaction().begin();
			
			Query q = em.createQuery("UPDATE Wachstum w SET w.keimung = :keimung , w.groesse = :groesse , w.datum =:datum WHERE w.wachstumID = :ID");
					  q.setParameter("keimung", keimungString);
					  q.setParameter("groesse", groesseString);
					  q.setParameter("datum", datumString);
					  q.setParameter("ID",wachstumID);
					  q.executeUpdate();
					  
			em.getTransaction().commit();
			em.close(); 
			return true;
			
		case 1:
			System.out.println("Update abgebrochen!");
			return false;
			
		}
		return false;
		
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();

		} catch (EingabeException e) {
			System.out.println("Eingabe Fehler");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für die Größe nur Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
		
	}

	private boolean hohleEingabe() throws EingabeException,NumberFormatException {
		
		keimungString = textfeldKeimung.getText();
		groesseDouble = Double.parseDouble(textfeldGroesse.getText());
		stringBuilder.append(groesseDouble).append(" cm");
		groesseString = stringBuilder.toString();
		stringBuilder.setLength(0);
		
		if(isEingabeLeer()){
			
			throw new EingabeException("Eine oder mehrere Eingaben fehlen.");
			
		
		}else{

			return true;
		}
}

	private void ueberpruefeDatum() throws EingabeException {
	
		hohleAussaatDatum();
		datumString = textfeldDatum.getText();
		
		if(istDatumVerwendbar()){
			
			/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
			Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
			so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
							
			String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
			String[] teilString = datumString.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
			 
			try {
				 aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
				
			} catch (ParseException e) {
				e.printStackTrace();
			}
			
			if(eingegebenesDatum.after(aktuellesDatum)){
				throw new EingabeException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
				
			// Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
			// um dies zu überprüfen wird der vorher gesplittete String genutzt
			}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0")) ){
			    throw new EingabeException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
			
			}else if(eingegebenesDatum.equals(aktuellesDatum)){
				System.out.println("Alles ok");
			}
			
		}else {
			throw new EingabeException("Das Datum der Bewässerung darf nicht vor dem Aussaat Datum liegen!");
		}
	}

	private boolean istDatumVerwendbar() {
		try {
			aussaatDatum = simpleDateFormat.parse(aussaatDatumString);
			eingegebenesDatum = simpleDateFormat.parse(datumString);
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}

		if(eingegebenesDatum.before(aussaatDatum)){
			return false;
			
		}
		return true;
	}

	private void hohleAussaatDatum() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));

		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		
		aussaatDatumString = aussaat.getAussaatDatum();
		
		em.close();
		
	}

	private boolean isEingabeLeer() {
	
		if(keimungString.length() == 0 || groesseDouble == 0.0 ){
	
			return true;
	
		}else{
	
			return false;
		}
	}

	private void fuegeWachstumEin() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();		
		
		Wachstum wachstum = new Wachstum();
		
		wachstum.setAussaat(aussaat);
		wachstum.setKeimung(keimungString);
		wachstum.setGroesse(groesseString);
		wachstum.setWachstumDatum(datumString);
		
		em.persist(aussaat);
		em.persist(wachstum);
		em.flush();
		em.getTransaction().commit();
		em.refresh(wachstum);
		em.refresh(aussaat);
		em.close(); 
		
	}

	private void einfügenEnde() {
	
		Object[] options = {"Fertig!","Neuer Wachstum!"};
		int selected = JOptionPane.showOptionDialog(null,"Wachstum hinzugefügt!", "Hinzufügen Erfolgreich", JOptionPane.YES_NO_OPTION,
				   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
	
		switch(selected){
		case 0:
			wachstumFrame.dispose();
			break;
		case 1:
			wachstumFrame.dispose();
			new FortschrittTabellenFenster(1);
			break;
		}
	}
}